#include <inputmanager.hpp>
#include <lock_manager/lock_manager.hpp>
#include <elog.h>
#include <autoinit.hpp>

#include "efsm.hpp"
#include "efsm_event.hpp"
#include <boost/thread.hpp>
#include <inputdev_func.hpp>

static boost::mutex mutex; 

admin_state_manmager* admin_state_manmager::p_admin_state_manmager_instance = NULL;


admin_state_manmager :: admin_state_manmager(){
}

admin_state_manmager :: ~admin_state_manmager(){
}

admin_state_manmager* admin_state_manmager::get_admin_state_manmager(){
    boost::unique_lock<boost::mutex> lock(mutex);
    
    if(p_admin_state_manmager_instance == NULL)  {
        p_admin_state_manmager_instance = new admin_state_manmager;
    }
    
    return p_admin_state_manmager_instance;
}

void admin_state_manmager :: Update(inputmanager* in_manager){
    
    this->dev_para = in_manager->getstate();
    log_i("input_type = %d,  input_code = %c \n",  this->dev_para->input_type, this->dev_para->input_code);
    log_i("input_value = %d, execption_id = %d \n",  this->dev_para->input_value, this->dev_para->execption_id);
}


void admin_status_auth_permission(EFSM_EVENT_TYPE event, void *arg){ 
    input_dev_param* local_arg = reinterpret_cast<input_dev_param*>(arg);

    inmanager_cmd(key_inputdev_type, e_input_cmd_auth, local_arg);
   
    return ;
}

/** 管理员模式下的 注册密码用户 选项 **/
/**
 * 现在的注册密码的写法，如果第一次失败了，例如密码长度过长啥的，就直接结束本次注册过程，返回失败。
 * 
 * 如果你希望实现第一次注册失败，后面还会增补一次机会，那么你可以在这里使用do{}-while()结构
 * ps:增补的情况，也要设置么一轮注册过程内的最大允许的失败次数。
 * 
 ***/
void admin_status_enroll_password_usr(EFSM_EVENT_TYPE event, void *arg){ 
    input_dev_param* plocal_arg = reinterpret_cast<input_dev_param*>(arg);

    /********** first enroll  *********/
    inmanager_cmd(key_inputdev_type, e_input_cmd_enroll, plocal_arg);

    if(curfuncnotdone == plocal_arg->isfuncdone){

        clear_input_dev_param(plocal_arg);
        
        /******* second enroll ******/
        inmanager_cmd(key_inputdev_type, e_input_cmd_enroll, plocal_arg);

        log_i("enroll result:status=[%d] 1=success\n", plocal_arg->status);

    }else if(curfunc_init == plocal_arg->isfuncdone){

        log_w("val of isfuncdone is not operated! \n");

    }else if(curfuncdone == plocal_arg->isfuncdone){
        log_v("the 1st enroll operation maybe canceled or enroll failed! \n");
    }else{

         log_e("ERR: undefined oparation! \n");
         assert(0);
    }

    return ;
}

void admin_status_enroll_new_admin(EFSM_EVENT_TYPE event, void *arg){ 
    input_dev_param* plocal_arg = reinterpret_cast<input_dev_param*>(arg);

    //inmanager_cmd(key_inputdev_type, e_input_cmd_enroll, plocal_arg);

    log_d("enroll result: plocal_arg->status= [ %d ]\n", plocal_arg->status);

    return ;
}
 
 
void exit_this_status(EFSM_EVENT_TYPE event, void *arg){ 
    input_dev_param* plocal_arg = reinterpret_cast<input_dev_param*>(arg);

    //inmanager_do_cancel_func(int execption_info) 该函数还未支持多设备的取消

    log_d("enroll result: plocal_arg->status= [ %d ]\n", plocal_arg->status);

    return ;
}
 

/* 1. define you own state name */
EFSM_CREATE(admin_mode_efsmsets);

 
/* 2. define a sets of event-handler */
static EFSM_SETS admin_mode_efsmsets[] = { 

/*** 2.1.验证权限 ****************/ 
    {event_auth_permission,        admin_status_auth_permission},  


/*** 2.2.管理员成功登陆后的选项 ***/

        /*** 2.2.1注册普通密码用户(添加新的普通密码用户，
         *        所谓普通用户，即其权限只能用于验证开门，不可以登录管理员) ***/
    {event_enroll_password_usr,    admin_status_enroll_password_usr},


        /*** 2.2.2注册普通手指用户(添加新的普通手指用户，
                  所谓普通用户，即其权限只能用于验证开门，不可以登录管理员) ***/


        /*** 2.2.3注册管理员用户(添加新的管理员) ***/
    {event_enroll_new_admin,       admin_status_enroll_new_admin},


/*** 3.退出当前管理员模式 *******/ 
    {event_exit_this_status,       exit_this_status},  
                                         
};
                        

void  admin_mode_init(void){	
	/* 3. bind your state to sets */
	EFSM_BIND(admin_mode_efsmsets,  admin_mode_efsmsets);	
}

auto_dev_init(admin_mode_init);


